// RT-Thread头文件
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include <rtdevice.h>
#include <board.h>

// HAL库头文件
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "rt_thread_demo.h"
#include "../hardware/USART_ALL/usart_all.h"        // Serial
#include "../hardware/MS53L/ms53l.h"                // MS53L
#include "../hardware/MS53L/iic2.h"                 // MS53L

/****************************** 宏定义区域 BEGIN *********************************
 * MS53L激光测距模块数据包格式相关宏定义
 ******************************************************************************/
#define MS53L_FRAME_HEADER1  0x64  // 'd'
#define MS53L_FRAME_HEADER2  0x3A  // ':'
#define MS53L_FRAME_TAIL     0x0A  // '\n'
#define MS53L_FRAME_LEN      4     // 有效数据长度（实际数字部分，通常为3或4位）

// 定义为1，则使用软件IIC，否则使用串口
#define IIC_MS53L 0
/****************************** 宏定义区域 END **********************************/

/****************************** 全局变量定义 BEGIN ******************************
 * ms53l_data      —— 存储有效数字
 * ms53l_distance  —— 距离值（单位：mm）
 ******************************************************************************/
uint8_t ms53l_data[MS53L_FRAME_LEN] = {0};
float ms53l_distance = 0;
/****************************** 全局变量定义 END ********************************/

/****************************** Ms53l_init BEGIN ********************************
 * 函    数：Ms53l_init
 * 功    能：初始化MS53L激光测距模块
 * 参    数：无
 * 返 回 值：无
 * 注意事项：根据IIC_MS53L宏选择IIC或串口初始化
 ******************************************************************************/
void Ms53l_init(void)
{
#if IIC_MS53L == 1
    IIC2_Init();           // 软件IIC初始化
#else
    usart3_init(9600);     // 串口3初始化 --激光测距 10Hz
#endif
}
/****************************** Ms53l_init END **********************************/

/****************************** MS53L_push BEGIN ********************************
 * 函    数：MS53L_push
 * 功    能：MS53L激光测距数据包接收状态机
 * 参    数：rx_data —— 接收到的字节
 * 返 回 值：1-接收完成，0-未完成
 * 注意事项：在串口中断回调中调用
 ******************************************************************************/
uint8_t MS53L_push(uint8_t rx_data)
{
    static uint8_t RxState = 0;      // 状态机状态
    static uint8_t pRxPacket = 0;    // 数据包内字节计数

    switch(RxState)
    {
        case 0: // 等待包头第一个字节
            if(rx_data == MS53L_FRAME_HEADER1)
                RxState = 1;
            break;
        case 1: // 等待包头第二个字节
            if(rx_data == MS53L_FRAME_HEADER2)
            {
                RxState = 2;
                pRxPacket = 0;
            }
            else
                RxState = 0;
            break;
        case 2: // 接收数据
            if(rx_data == MS53L_FRAME_TAIL)
            {
                // 数据接收完成，数据长度为pRxPacket
                // 数据存储在 ms53l_data[0~pRxPacket-1]
                // 若不足4位，后面补0
                for(uint8_t i = pRxPacket; i < MS53L_FRAME_LEN; i++)
                    ms53l_data[i] = 0x20; // 补空格
                RxState = 0;
                return 1;
            }
            else
            {
                if(pRxPacket < MS53L_FRAME_LEN)
                    ms53l_data[pRxPacket++] = rx_data;
                // 超过最大长度则丢弃后续数据
            }
            break;
        default:
            RxState = 0;
            break;
    }
    return 0;
}
/****************************** MS53L_push END **********************************/

/****************************** 数据更新函数 BEGIN *******************************
 * 函    数：distance_update
 * 功    能：解析并更新激光测距数据
 * 参    数：无
 * 返 回 值：无
 * 注意事项：在MS53L_push返回1后调用
 ******************************************************************************/
void distance_update(void)
{
    uint8_t l_cnt = 0;
    uint8_t l_arr[MS53L_FRAME_LEN] = {0};
    uint16_t ret1 = 0;

    // 过滤空格，只保留数字
    for(int i = 0; i < MS53L_FRAME_LEN; i++)
    {
        if(ms53l_data[i] != 0x20)
            l_arr[l_cnt++] = ms53l_data[i];
    }
    for(int i = 0; i < l_cnt; i++)
    {
        uint8_t dec_value = 0;
        if(l_arr[i] >= 0x30 && l_arr[i] <= 0x39) // '0'-'9'
            dec_value = l_arr[i] - 0x30;
        else
            dec_value = 0;
        ret1 = ret1 * 10 + dec_value;
    }
    ms53l_distance = (float)ret1;
}
/****************************** 数据更新函数 END ********************************/

